﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using System.Threading.Tasks;

namespace TriageQueueSystem.InterfacesImplementation
{
    public class InterfaceBase : IInterfaceBase
    {
        public InterfaceBase(IHttpHelper httpHelper)
        {
            this.HttpHelper = httpHelper;
            this.ServiceUrl = ConfigurationManager.AppSettings["ServerUrl"];
            this.ApiRouted = ConfigurationManager.AppSettings["ApiRouted"];
            this.OneParamStringFormat = ConfigurationManager.AppSettings["OneParamStringFormat"];
            this.NoParamStringFormat = ConfigurationManager.AppSettings["NoParamStringFormat"];
        }

        #region 字段及属性
        /// <summary>
        /// api路由基础地址
        /// <para>
        ///     请确保服务名称和Api端控制器名称一至。
        ///     例如：string.Format(ApiRouted, nameof(服务名称).Replace("Service", ""));
        ///     使其结果变为：/api/TraigeConfig/
        /// </para>
        /// </summary>
        public string ApiRouted = "/api/{0}/";

        /// <summary>
        /// {0}{1}?{2}={3}
        /// <para>
        ///     string.Format("{0}{1}?{2}={3}", this.FullService, nameof(this.Get), nameof(id), id)
        /// </para>
        /// </summary>
        protected readonly string OneParamStringFormat = "{0}{1}?{2}={3}";

        /// <summary>
        /// {0}{1}
        /// <para>
        ///     this.HttpHelper.HttpGet(string.Format("{0}{1}", this.FullService, nameof(this.GetAll))
        /// </para>
        /// </summary>
        protected readonly string NoParamStringFormat = "{0}{1}";

        /// <summary>
        /// 服务端URL
        /// </summary>
        public string ServiceUrl { get; protected set; }

        /// <summary>
        /// 最终成型列子：http://localhost:55173/api/TriageKnowLedges/
        /// </summary>
        public string FullService { get;protected set; }

        protected IHttpHelper HttpHelper { get;private set; }
        #endregion


        #region 方法
        #region 一般通用方法
        protected virtual T Get<T>(string id)
            => this.BaseGetInfo<T>(this.FullService, nameof(this.Get), nameof(id), id);

        protected virtual List<T> GetAll<T>()
            => BaseGetInfoByNoParam<List<T>>(this.FullService, nameof(this.GetAll));

        protected virtual T BaseGetInfoByNoParam<T>(string serviceFullName, string methodName)
            => ToObj<T>(this.HttpHelper.HttpGet(string.Format(this.NoParamStringFormat, serviceFullName, methodName)));

        protected virtual async Task<T> BaseGetInfoByNoParamAsync<T>(string serviceFullName, string methodName)
            => ToObj<T>(await this.HttpHelper.HttpGetAsync(string.Format(this.NoParamStringFormat, serviceFullName, methodName)));

        /// <summary>
        /// 适用于 <see cref="OneParamStringFormat"/> 地址模式的HttpGet方法
        /// 
        /// </summary>
        /// <typeparam name="T">返回类型参数</typeparam>
        /// <param name="serviceFullName">完整服务名<see cref="FullService"/></param>
        /// <param name="methodName">当前方法名 <para>nameof(QueryByName)</para></param>
        /// <param name="paramName">参数名 <para>nameof(name)</para></param>
        /// <param name="param">参数</param>
        /// <remarks>
        ///     例如：
        ///         base.BaseGetInfo<List<TriageKnowLedgesDto>>(this.FullService, nameof(QueryByName), nameof(name), name);
        /// </remarks>
        /// <returns></returns>
        protected virtual T BaseGetInfo<T>(string serviceFullName, string methodName, string paramName, string param)
            => ToObj<T>(this.HttpHelper.HttpGet(string.Format(this.OneParamStringFormat, serviceFullName,
                                                                                            methodName,
                                                                                            paramName,
                                                                                            param)));

        /// <summary>
        /// <see cref="BaseGetInfo"/> 的异步方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceFullName"></param>
        /// <param name="methodName"></param>
        /// <param name="paramName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        protected virtual async Task<T> BaseGetInfoAsync<T>(string serviceFullName, string methodName, string paramName, string param)
            => ToObj<T>(await this.HttpHelper.HttpGetAsync(string.Format(this.OneParamStringFormat, serviceFullName,
                                                                                            methodName,
                                                                                            paramName,
                                                                                            param)));

        /// <summary>
        /// 适用于 <see cref="OneParamStringFormat"/> 地址模式的HttpPost方法
        /// <para>Json数据</para>
        /// </summary>
        /// <typeparam name="T">返回类型参数</typeparam>
        /// <param name="serviceFullName">完整服务名<see cref="FullService"/></param>
        /// <param name="methodName">当前方法名 <para>nameof(QueryByName)</para></param>
        /// <param name="param">参数</param>
        /// <remarks>
        ///     例如：
        ///         base.BaseGetInfo<List<TriageKnowLedgesDto>>(this.FullService, nameof(QueryByName), name);
        /// </remarks>
        /// <returns></returns>     
        protected virtual T BasePostInfo<T>(string serviceFullName, string methodName, string param)
            => ToObj<T>(this.HttpHelper.HttpPost(string.Format(this.NoParamStringFormat, serviceFullName,methodName)
                                                    ,param));
        /// <summary>
        /// 
        /// <para>Json数据</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceFullName"></param>
        /// <param name="methodName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        protected virtual async Task<T> BasePostInfoAsync<T>(string serviceFullName, string methodName, string param)
            => ToObj<T>(await this.HttpHelper.HttpPostAsync(string.Format(this.NoParamStringFormat, serviceFullName, methodName)
                                                                , param));

        /// <summary>
        /// <para>使用键值对参数</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceFullName"></param>
        /// <param name="methodName"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        protected virtual T BasePostInfoByParam<T>(string serviceFullName, string methodName, string param)
            => ToObj<T>(this.HttpHelper.HttpPostForManyParam(string.Format(this.NoParamStringFormat, serviceFullName, methodName)
                                                                , param));
        protected virtual async Task<T> BasePostInfoByParamAsync<T>(string serviceFullName, string methodName, string param)
            => ToObj<T>(await this.HttpHelper.HttpPostForManyParamAsync(string.Format(this.NoParamStringFormat, serviceFullName, methodName)
                                                                , param));
        #endregion
        /// <summary>
        /// 获取完整服务端接口地址
        /// </summary>
        /// <param name="serviceUrl">接口地址</param>
        /// <param name="apiRouted">控制器地址</param>
        /// <returns></returns>
        protected virtual string GetFullServiceName(string serviceUrl, string apiRouted)
              => string.Format("{0}{1}", this.ServiceUrl, this.ApiRouted);

        public virtual T ToObj<T>(string data)
            => Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data);

        public virtual string ToJsonStr(object obj)
            => Newtonsoft.Json.JsonConvert.SerializeObject(obj);

        #endregion
    }
}
